package com.cloud.lan.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cloud.lan.api.dto.req.LanTagCfgReq;
import com.cloud.lan.dao.LanTagUserRecordMapper;
import com.cloud.lan.dao.LanUserFavouritesMapper;
import com.cloud.lan.dao.LanUserMapper;
import com.cloud.lan.dao.LanUserWxMapper;
import com.cloud.lan.entity.base.ListResponse;
import com.cloud.lan.entity.constant.TagConstant;
import com.cloud.lan.entity.model.dataobject.LanTagCfgDO;
import com.cloud.lan.entity.model.dataobject.LanTagUserRecordDO;
import com.cloud.lan.entity.model.dataobject.LanUserDO;
import com.cloud.lan.entity.model.dataobject.LanUserFavouritesDO;
import com.cloud.lan.entity.model.dataobject.LanUserWxDO;
import com.cloud.lan.service.ILanTagCfgService;
import com.cloud.lan.service.ILanTagUserService;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;

/**
 * Created by zhouquan on 2022/4/14.
 */
@Slf4j
@Service
public class LanTagUserServiceImpl implements ILanTagUserService{

    @Resource
    private LanUserMapper lanUserMapper;
    @Resource
    private LanTagUserRecordMapper lanTagUserRecordMapper;
    @Resource
    private LanUserWxMapper lanUserWxMapper;
    @Resource
    private LanUserFavouritesMapper lanUserFavouritesMapper;
    @Autowired
    private ILanTagCfgService iLanTagCfgService;

    private final int pageSize = TagConstant.TAG_USER_PAGESIZE;

    @Override
    public List<LanUserDO> queryUserByTag(LanTagCfgDO cfgDO,int pageIndex) {
        if(pageIndex == 0){
            pageIndex = 1;
        }
        List<LanUserDO> userDOS = new ArrayList<>();
        //实时标签-查询表lan_user
        if(cfgDO.getTagType() == 1){
            //店铺--相关标签
            LambdaQueryWrapper<LanUserDO> qw = new LambdaQueryWrapper<>();
            qw.eq(LanUserDO::getIsDeleted,0);
            qw.isNotNull(LanUserDO::getUserPhone);
            qw.ne(LanUserDO::getUserPhone,"");
            if(StringUtils.equalsIgnoreCase("tagshop1",cfgDO.getTagCode())
                    || StringUtils.equalsIgnoreCase("tagshop2",cfgDO.getTagCode())
                    || StringUtils.equalsIgnoreCase("tagshop3",cfgDO.getTagCode())
                    || StringUtils.equalsIgnoreCase("tagshop4",cfgDO.getTagCode())){

                qw.eq(LanUserDO::getIntroduce, cfgDO.getTagVal());
                Page<LanUserDO> page = new Page<>(pageIndex, pageSize);
                IPage<LanUserDO> pageList = lanUserMapper.selectPage(page, qw);
                if(CollectionUtils.isNotEmpty(pageList.getRecords())){
                    return pageList.getRecords();
                }
            }

            //推荐人标签--相关标签
            if(StringUtils.equalsIgnoreCase("tagrecommend",cfgDO.getTagCode())){
                if(StringUtils.isNotBlank(cfgDO.getTagVal())){
                    qw.eq(LanUserDO::getRecommender, cfgDO.getTagVal());
                }else{
                    qw.isNotNull(LanUserDO::getRecommender);
                    qw.ne(LanUserDO::getRecommender,"");
                }
                Page<LanUserDO> page = new Page<>(pageIndex, pageSize);
                IPage<LanUserDO> pageList = lanUserMapper.selectPage(page, qw);
                if(CollectionUtils.isNotEmpty(pageList.getRecords())){
                    return pageList.getRecords();
                }
            }
            //全量人群标签
            if(StringUtils.equalsIgnoreCase("tagalluser",cfgDO.getTagCode())){
                Page<LanUserDO> page = new Page<>(pageIndex, pageSize);
                IPage<LanUserDO> pageList = lanUserMapper.selectPage(page, qw);
                if(CollectionUtils.isNotEmpty(pageList.getRecords())){
                    return pageList.getRecords();
                }
            }
        }else{
            //非实时标签-查询标签用户表
            LambdaQueryWrapper<LanTagUserRecordDO> qw = new LambdaQueryWrapper<>();
            qw.eq(LanTagUserRecordDO::getTagCode,cfgDO.getTagCode());
            qw.eq(LanTagUserRecordDO::getIsDeleted,0);
            Page<LanTagUserRecordDO> page = new Page<>(pageIndex, pageSize);
            IPage<LanTagUserRecordDO> pageList = lanTagUserRecordMapper.selectPage(page, qw);
            if(CollectionUtils.isNotEmpty(pageList.getRecords())){
                pageList.getRecords().stream().forEach(tur->{
                    LanUserDO userDO = new LanUserDO();
                    userDO.setUserId(tur.getUserId());
                    userDO.setUserPhone(tur.getMobile());
                    userDOS.add(userDO);
                });
            }
        }
        return userDOS;
    }

    @Override
    public int totalCount(LanTagCfgDO cfgDO) {
        //实时标签-查询表lan_user
        if(cfgDO.getTagType() == 1){
            //店铺--相关标签
            LambdaQueryWrapper<LanUserDO> qw = new LambdaQueryWrapper<>();
            qw.eq(LanUserDO::getIsDeleted,0);
            qw.isNotNull(LanUserDO::getUserPhone);
            qw.ne(LanUserDO::getUserPhone,"");
            if(StringUtils.equalsIgnoreCase("tagshop1",cfgDO.getTagCode())
                    || StringUtils.equalsIgnoreCase("tagshop2",cfgDO.getTagCode())
                    || StringUtils.equalsIgnoreCase("tagshop3",cfgDO.getTagCode())
                    || StringUtils.equalsIgnoreCase("tagshop4",cfgDO.getTagCode())){

                qw.eq(LanUserDO::getIntroduce, cfgDO.getTagVal());
                int totalCount = lanUserMapper.selectCount(qw);
                log.info("tagCode:[{}] 标签对应总数:[{}]",cfgDO.getTagCode(),totalCount);
                return totalCount;
            }

            //推荐人标签--相关标签
            if(StringUtils.equalsIgnoreCase("tagrecommend",cfgDO.getTagCode())){
                if(StringUtils.isNotBlank(cfgDO.getTagVal())){
                    qw.eq(LanUserDO::getRecommender, cfgDO.getTagVal());
                }else{
                    qw.isNotNull(LanUserDO::getRecommender);
                    qw.ne(LanUserDO::getRecommender,"");
                }
                int totalCount = lanUserMapper.selectCount(qw);
                log.info("tagCode:[{}] 标签对应总数:[{}]",cfgDO.getTagCode(),totalCount);
                return totalCount;
            }
            //全量人群标签
            if(StringUtils.equalsIgnoreCase("tagalluser",cfgDO.getTagCode())){
                int totalCount = lanUserMapper.selectCount(qw);
                log.info("tagCode:[{}] 标签对应总数:[{}]",cfgDO.getTagCode(),totalCount);
                return totalCount;
            }
        }else{
            //非实时标签-查询标签用户表
            LambdaQueryWrapper<LanTagUserRecordDO> qw = new LambdaQueryWrapper<>();
            qw.eq(LanTagUserRecordDO::getTagCode,cfgDO.getTagCode());
            qw.eq(LanTagUserRecordDO::getIsDeleted,0);
            int totalCount = lanTagUserRecordMapper.selectCount(qw);
            log.info("tagCode:[{}] 标签对应总数:[{}]",cfgDO.getTagCode(),totalCount);
            return totalCount;
        }
        log.info("tagCode:[{}] 标签对应总数:[{}]",cfgDO.getTagCode(),0);
        return 0;
    }

    @Override
    public void timeHandle(String tagCode) {
        //标签配置查询
        LanTagCfgReq cfgReq = new LanTagCfgReq();
        cfgReq.setTagCodes(tagCode);
        ListResponse<List<LanTagCfgDO>> tagCfgListResp = iLanTagCfgService.queryTagCfgList(cfgReq);
        List<LanTagCfgDO> tagCfgDOList = tagCfgListResp.getData();
        if(CollectionUtils.isEmpty(tagCfgDOList)){
            log.warn("标签离线处理.标签配置不存在.tagCode:[{}]",tagCode);
            return;
        }
        //先删除
        LambdaQueryWrapper<LanTagUserRecordDO> qw = new LambdaQueryWrapper<>();
        qw.eq(LanTagUserRecordDO::getTagCode,tagCode);
        lanTagUserRecordMapper.delete(qw);

        if(StringUtils.equalsIgnoreCase(TagConstant.TAG_VISIT1MONTH,tagCode)
                || StringUtils.equalsIgnoreCase(TagConstant.TAG_VISIT2WEEK,tagCode)){
            handle1(tagCfgDOList.get(0));
        }else if(StringUtils.equalsIgnoreCase(TagConstant.TAG_USERFAVOURITES,tagCode)){
            handle2(tagCfgDOList.get(0));
        }
    }

    private void handle1(LanTagCfgDO tagCfgDO){
        String tagCode = tagCfgDO.getTagCode();
        log.info("用户访问记录标签离线处理.tagCode:[{}]",tagCode);
        //查询lan_user_wx
        int days = 5;
        if(StringUtils.equalsIgnoreCase(TagConstant.TAG_VISIT1MONTH,tagCode)){
            days = 30;
        }else if(StringUtils.equalsIgnoreCase(TagConstant.TAG_VISIT2WEEK,tagCode)){
            days = 15;
        }

        int pageIndex = 1;
        for(;;){
            List<LanUserWxDO> userWxDOS = queryUserWxList(pageIndex,days);
            pageIndex ++ ;
            log.info("用户访问记录标签离线处理.tagCode:[{}] 用户微信表记录数:[{}]",tagCode,userWxDOS.size());
            if(CollectionUtils.isEmpty(userWxDOS)){
                break;
            }
            List<String> openIdList = userWxDOS.stream().filter(uw->StringUtils.isNotBlank(uw.getOpenId())).map(LanUserWxDO::getOpenId).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(openIdList)){
                LambdaQueryWrapper<LanUserDO> qw2 = new LambdaQueryWrapper<>();
                qw2.in(LanUserDO::getOpenId, openIdList);
                qw2.eq(LanUserDO::getIsDeleted,0);
                List<LanUserDO> userDOS = lanUserMapper.selectList(qw2);
                if(CollectionUtils.isNotEmpty(userDOS)){
                    log.info("用户访问记录标签离线处理.tagCode:[{}] 用户表记录数:[{}]",tagCode,userDOS.size());
                    LambdaQueryWrapper<LanTagUserRecordDO> turqw = new LambdaQueryWrapper<>();
                    turqw.eq(LanTagUserRecordDO::getTagCode,tagCode);
                    turqw.eq(LanTagUserRecordDO::getIsDeleted,0);
                    userDOS.stream().forEach(ud->{
                        turqw.eq(LanTagUserRecordDO::getUserId,ud.getUserId());
                        int nums = lanTagUserRecordMapper.selectCount(turqw);
                        if(nums == 0 && StringUtils.isNotBlank(ud.getUserPhone())){
                            LanTagUserRecordDO recordDO = new LanTagUserRecordDO();
                            recordDO.setTagCode(tagCode);
                            recordDO.setUserId(ud.getUserId());
                            recordDO.setMobile(ud.getUserPhone());
                            Date now = new Date();
                            recordDO.setCreateTime(now);
                            recordDO.setUpdateTime(now);
                            lanTagUserRecordMapper.insert(recordDO);
                        }
                    });
                }
            }
        }
    }


    private List<LanUserWxDO> queryUserWxList(int pageIndex,int days){
        LambdaQueryWrapper<LanUserWxDO> qw = new LambdaQueryWrapper<>();
        Date startD = DateUtils.addDays(new Date(),-(days));
        qw.ge(LanUserWxDO::getCreateTime, startD);
        Page<LanUserWxDO> page = new Page<>(pageIndex, pageSize);
        IPage<LanUserWxDO> pageList = lanUserWxMapper.selectPage(page, qw);
        if(CollectionUtils.isNotEmpty(pageList.getRecords())){
            return pageList.getRecords();
        }
        return new ArrayList<>();
    }

    private void handle2(LanTagCfgDO tagCfgDO){
        log.info("收藏夹标签离线处理.tagCfgDO:[{}]", JSON.toJSONString(tagCfgDO));
        String goodIds = tagCfgDO.getTagVal();
        if(StringUtils.isNotBlank(goodIds)){
            Stream.of(goodIds.split(";")).forEach(gd->{
                if(StringUtils.isNotBlank(gd) && Long.parseLong(gd)>0){
                    handle2goodId(tagCfgDO.getTagCode(),Long.parseLong(gd));
                }
            });
        }
    }

    private void handle2goodId(String tagCode,Long goodsId){
        int pageIndex = 1;
        for(;;){
            List<LanUserFavouritesDO> userFavouritesDOList = queryUserFavouritesList(pageIndex,goodsId);
            pageIndex ++ ;
            log.info("收藏夹标签离线处理.tagCode:[{}] 用户收藏夹表记录数:[{}]",tagCode,userFavouritesDOList.size());
            if(CollectionUtils.isEmpty(userFavouritesDOList)){
                break;
            }
            List<Long> userIdList = userFavouritesDOList.stream().filter(uw->Objects.nonNull(uw.getUserId()) && uw.getUserId()>0).map(LanUserFavouritesDO::getUserId).collect(Collectors.toList());
            if(CollectionUtils.isNotEmpty(userIdList)){
                LambdaQueryWrapper<LanUserDO> qw2 = new LambdaQueryWrapper<>();
                qw2.in(LanUserDO::getUserId, userIdList);
                qw2.eq(LanUserDO::getIsDeleted,0);
                List<LanUserDO> userDOS = lanUserMapper.selectList(qw2);
                if(CollectionUtils.isNotEmpty(userDOS)){
                    log.info("收藏夹标签离线处理.tagCode:[{}] 用户表记录数:[{}]",tagCode,userDOS.size());
                    LambdaQueryWrapper<LanTagUserRecordDO> turqw = new LambdaQueryWrapper<>();
                    turqw.eq(LanTagUserRecordDO::getTagCode,tagCode);
                    turqw.eq(LanTagUserRecordDO::getIsDeleted,0);
                    userDOS.stream().forEach(ud->{
                        turqw.eq(LanTagUserRecordDO::getUserId,ud.getUserId());
                        int nums = lanTagUserRecordMapper.selectCount(turqw);
                        if(nums == 0 && StringUtils.isNotBlank(ud.getUserPhone())){
                            LanTagUserRecordDO recordDO = new LanTagUserRecordDO();
                            recordDO.setTagCode(tagCode);
                            recordDO.setUserId(ud.getUserId());
                            recordDO.setMobile(ud.getUserPhone());
                            Date now = new Date();
                            recordDO.setCreateTime(now);
                            recordDO.setUpdateTime(now);
                            lanTagUserRecordMapper.insert(recordDO);
                        }
                    });
                }
            }
        }
    }

    private List<LanUserFavouritesDO> queryUserFavouritesList(int pageIndex, Long goodsId){
        LambdaQueryWrapper<LanUserFavouritesDO> qw = new LambdaQueryWrapper<>();
        qw.eq(LanUserFavouritesDO::getStatus, 1);
        qw.eq(LanUserFavouritesDO::getGoodsId, goodsId);
        qw.eq(LanUserFavouritesDO::getIsDeleted, 0);
        Page<LanUserFavouritesDO> page = new Page<>(pageIndex, pageSize);
        IPage<LanUserFavouritesDO> pageList = lanUserFavouritesMapper.selectPage(page, qw);
        if(CollectionUtils.isNotEmpty(pageList.getRecords())){
            return pageList.getRecords();
        }
        return new ArrayList<>();
    }


    public static void main(String[] args){
        String str = "1;2;3";
        Stream.of(str.split(";")).forEach(st->{
            System.out.println("结果:"+st);
            int pageIndex = 1;
            for(;;){
                System.out.println("结果pageIndex:"+st+pageIndex);

                if(pageIndex ==2){
                    break;
                }
                pageIndex ++ ;
            }
        });
    }

    @Override
    public int queryTagUserNums(LanTagCfgDO cfgDO) {
        int totalNums = 0;
        if(cfgDO.getTagType() == 1){
            LambdaQueryWrapper<LanUserDO> qw = new LambdaQueryWrapper<>();
            qw.eq(LanUserDO::getIsDeleted,0);
            qw.isNotNull(LanUserDO::getUserPhone);
            qw.ne(LanUserDO::getUserPhone,"");
            //店铺--相关标签
            if(StringUtils.equalsIgnoreCase("tagshop1",cfgDO.getTagCode())
                    || StringUtils.equalsIgnoreCase("tagshop2",cfgDO.getTagCode())
                    || StringUtils.equalsIgnoreCase("tagshop3",cfgDO.getTagCode())
                    || StringUtils.equalsIgnoreCase("tagshop4",cfgDO.getTagCode())){
                qw.eq(LanUserDO::getIntroduce, cfgDO.getTagVal());
                totalNums = lanUserMapper.selectCount(qw);
            }

            //推荐人标签--相关标签
            if(StringUtils.equalsIgnoreCase("tagrecommend",cfgDO.getTagCode())){
                if(StringUtils.isNotBlank(cfgDO.getTagVal())){
                    qw.eq(LanUserDO::getRecommender, cfgDO.getTagVal());
                }else{
                    qw.isNotNull(LanUserDO::getRecommender);
                    qw.ne(LanUserDO::getRecommender,"");
                }
                totalNums = lanUserMapper.selectCount(qw);
            }
            //全量人群标签
            if(StringUtils.equalsIgnoreCase("tagalluser",cfgDO.getTagCode())){
                totalNums = lanUserMapper.selectCount(qw);
            }
        }else{
            LambdaQueryWrapper<LanTagUserRecordDO> turqw = new LambdaQueryWrapper<>();
            turqw.eq(LanTagUserRecordDO::getTagCode,cfgDO.getTagCode());
            turqw.eq(LanTagUserRecordDO::getIsDeleted,0);
            totalNums = lanTagUserRecordMapper.selectCount(turqw);
        }
        return totalNums;
    }
}
